package com.gpipe.dbwriter;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger;

import com.gpipe.dirwatcherRealtime.DirectorySnapshotRealtime;
import com.gpipe.tools.GpipeInit;

/*
 * author:zhengrx
 */
public abstract class AbstractSendResultData {
	protected String dbtns;
	protected String dbclass;
	protected String username;
	protected String password;
	
//	protected PreparedStatement prepStatement;
	protected AtomicInteger counter;
	protected int batchSize = 20000;
	
	public Connection createConnect(){
		Properties prop = new Properties();   
        InputStream in = Object.class.getResourceAsStream("/com/gpipe/properties/db.properties");   
        try {   
            prop.load(in);   
            dbclass = prop.getProperty("db.driverClassName").trim();   
            dbtns = prop.getProperty("db.url").trim(); 
            username = prop.getProperty("db.username").trim(); 
            password = prop.getProperty("db.password").trim(); 
        } catch (IOException e) {   
            e.printStackTrace();   
        }
		Connection conn = null;
		try {
			Class.forName(dbclass);
			conn = DriverManager.getConnection(dbtns,username,password);
		} catch (ClassNotFoundException | SQLException e) {
			e.printStackTrace();
		}
		return conn;
	}
	
	protected void executeBatch(PreparedStatement prepStatement) throws SQLException {
		prepStatement.executeBatch();
		prepStatement.clearBatch();
		counter = new AtomicInteger(0);
	}
	
	protected void writeMysql(BufferedReader reader,Connection connection,String insertQuery,int cols){
		PreparedStatement prepStatement = null;
		if(connection==null){
			connection = createConnect();
		}
		if(connection==null){
			GpipeInit.writeLogs("can not connect to mysql, please check status of mysql service.");
			System.exit(0);
		}
//		StringBuilder insertQuery = new StringBuilder("INSERT INTO signal_data_gz(MSG_TYPE,MSG_SUB_TYPE,ACC_NBR,LAC,CI,START_TIME)VALUES(?,?,?,?,?,?)");
		try {
			prepStatement = connection.prepareStatement(insertQuery.toString());
		} catch (SQLException e) {
			e.printStackTrace();
		}
        	String line = null;
    		try {
				while ((line = reader.readLine()) != null){
					if (line != null){
						String[] fields=null;
						fields = line.split("\\|",-1);
						//2,3,5,9,10,11
						if(fields.length>=cols){
							try {
								prepStatement.setString(1, fields[2]);
								prepStatement.setString(2, fields[3]);
								prepStatement.setString(3, fields[5]);
								prepStatement.setString(4, fields[9]);
								prepStatement.setString(5, fields[10]);
								prepStatement.setString(6, fields[11]);
								prepStatement.addBatch();
				    			counter.incrementAndGet();
				    			if (counter.get() == batchSize){
				    				executeBatch(prepStatement);
				    			}
				    			
				    			
				    			
							}catch(Exception e){
								e.printStackTrace();
							}
						}
					}
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
    		if(counter.get()>0){
    			try {
					executeBatch(prepStatement);
				} catch (SQLException e) {
					e.printStackTrace();
				}
    		}
    		
    		try {
				prepStatement.close();
    		if(!connection.isClosed()){
				connection.close();
			}
    		} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		
	}
	/**
	 * 
	 * @param result the data to insert
	 * @param connection database connection
	 * @param insertQuery insert sql
	 * @param cols the num of columns to insert
	 * @param name the name of this thread
	 * @param amplificationFlag the flag whether or not to amplify the num
	 */
	protected void writeMysql(Map result,Connection connection,String insertQuery,int cols,String name,boolean amplificationFlag){
		PreparedStatement prepStatement = null;
		if(connection==null){
			connection = createConnect();
		}
		if(connection==null){
			GpipeInit.writeLogs("can not connect to mysql, please check status of mysql service.");
			System.exit(0);
		}
		String startTime = GpipeInit.writeLogs("Start to writedata '"+name+"' into mysql");
		try {
			connection.setAutoCommit(false);
			prepStatement = connection.prepareStatement(insertQuery.toString());
		} catch (SQLException e) {
			e.printStackTrace();
		}
        	String line = null;
        	counter = new AtomicInteger(0);
    		Iterator iter = result.entrySet().iterator();
    		System.out.println("!!!!---"+Thread.currentThread().getId()+"-"+Thread.currentThread().getName()+"-"+name);
			while (iter.hasNext()) {
				  Map.Entry entry = (Map.Entry) iter.next();
				  Object key = entry.getKey();
				  Object value = entry.getValue();
				  if(amplificationFlag){
					  line = key+"|"+GpipeInit.proportionRound(value.toString());
				  }else{
					  line = key+"|"+value;
				  }
				  
				  if (line != null){
					String[] fields=null;
					fields = line.split("\\|",-1);
					//2,3,5,9,10,11
					if(fields.length>=cols){
						try {
				    			for(int i=0;i<cols;i++){
									prepStatement.setString(i+1, fields[i]);
								}
									prepStatement.addBatch();
					    			counter.incrementAndGet();
					    			if (counter.get() == batchSize){
					    				executeBatch(prepStatement);
					    				connection.commit();
					    			}
						}catch(Exception e){
							e.printStackTrace();
						}
					}
				}
			}
    		if(counter.get()>0){
    			try {
					executeBatch(prepStatement);
					connection.commit();
				} catch (SQLException e) {
					e.printStackTrace();
				}
    		}
    		
    		String endTime = GpipeInit.writeLogs("Finish writing '"+name+"' data into mysql");
				System.out.println("----insert '"+name+"' data duration="+GpipeInit.duration(startTime,endTime,"yyyy-MM-dd HH:mm:ss")+"s");
    		try {
				if(!connection.isClosed()){
					connection.close();
				}
				prepStatement.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    		
	}

}
